package com.sxj.corejava.code08_常用类.String;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.sql.SQLOutput;
import java.util.Arrays;

/**
 * @author 石小俊
 */
public class Test06_字符集 {

    public static void main(String[] args) throws UnsupportedEncodingException {
//        showEncoding();
//        encoded();
//        decoded();
//        garbled();
//        garbled2();
        garbled3();
    }

    public static void showEncoding() {
        // 当前系统所使用的字符集
        System.out.println("当前系统所使用的字符集:" + System.getProperty("file.encoding"));
        // JVM默认使用的字符集即为当前系统的字符集
        System.out.println("JVM默认使用的字符集:" + Charset.defaultCharset());
    }

    /**
     * 编码:将具体数据转换成二进制数据,用于存储到计算机中
     */
    public static void encoded() throws UnsupportedEncodingException {
//        String s = "Hello World";
        String s = "你好";
        // 编码,通过默认字符UTF-8集编码
        // 对于UTF-8字符集,中文占3个字节
        byte[] bs = s.getBytes();
        System.out.println(Arrays.toString(bs));

        // 使用GBK进行编码,中文占2个字节
        byte[] bs2 = s.getBytes("GBK");
        System.out.println(Arrays.toString(bs2));
    }

    /**
     * 解码,读取到存储在计算机中的二进制数据,将其转换成具体的数据
     */
    public static void decoded() throws UnsupportedEncodingException {
        byte[] bs = {-28, -67, -96, -27, -91, -67};
        byte[] bs2 = {-60, -29, -70, -61};

        // 使用系统默认字符集UTF-8进行解码
        String s = new String(bs);
        System.out.println(s);

        // 使用指定字符集GBK进行解码
        String s2 = new String(bs2, "GBK");
        System.out.println(s2);
    }

    /**
     * 乱码:当编码与解码所使用的字符集不一致时,会产生乱码
     */
    public static void garbled() throws UnsupportedEncodingException {
        String s = "你好";
        // 编码:使用GBK字符集进行编码
        byte[] bs = s.getBytes("GBK");
        System.out.println("使用GBK字符集进行编码:" + Arrays.toString(bs));
        // 解码:使用GBK解码
        String s2 = new String(bs, "GBK");
        System.out.println("使用GBK解码:" + s2);
        // 解码:使用ISO-8859-1字符集进行解码
        String s3 = new String(bs, "ISO-8859-1");
        System.out.println("使用ISO-8859-1字符集进行解码:" + s3);
        // 解码:使用默认字符集UTF-8字符集进行解码
        String s4 = new String(bs);
        System.out.println("使用默认字符集UTF-8字符集进行解码:" + s4);

        // 当出现乱码之后,某些乱码可以通过一定的方式进行解码
        // s3通过ISO-8859-1解码后导致的乱码,应该通过GBK解码才能正常展示
        // 因此,将乱码数据通过ISO-8859-1重新编码
        byte[] bs3 = s3.getBytes("ISO-8859-1");
        System.out.println("将乱码数据通过ISO-8859-1重新编码:" + Arrays.toString(bs3));
        // 然后再通过GBK重新解码
        s3 = new String(bs3, "GBK");
        System.out.println("通过GBK重新解码后:" + s3);

        // 对于s4的乱码进行重新编码与解码
        byte[] bs4 = s4.getBytes("UTF-8");
        System.out.println("将乱码数据通过UTF-8重新编码:" + Arrays.toString(bs4));
    }

    /**
     * 无法接乱乱码的场景
     * 由于GBK不符合UTF-8的规则,无法解决乱码问题
     * @throws UnsupportedEncodingException
     */
    public static void garbled2() throws UnsupportedEncodingException {
        String s = "你好";
        // 编码:使用GBK字符集进行编码
        byte[] bs = s.getBytes("GBK");
        System.out.println("使用GBK字符集进行编码:" + Arrays.toString(bs));
        // 解码:使用默认字符集UTF-8字符集进行解码
        String s2 = new String(bs);
        System.out.println("使用默认字符集UTF-8字符集进行解码:" + s2);
        // 对于s4的乱码进行重新编码与解码
        byte[] bs2 = s2.getBytes("UTF-8");
        System.out.println("将乱码数据通过UTF-8重新编码:" + Arrays.toString(bs2));
        // 使用GBK解码
        String s3 = new String(bs2, "GBK");
        System.out.println(s3);

    }

    public static void garbled3() throws UnsupportedEncodingException {
        String s = "你好";
        // 使用UTF-8编码
        byte[] bs = s.getBytes();
        // 使用GBK解码
        String s2 = new String(bs, "GBK");
        System.out.println(s2);

        // 解决乱码问题
//        String s3 = new String(s2.getBytes("GBK"), "UTF-8");
        // 可以省略掉系统默认字符集
        String s3 = new String(s2.getBytes("GBK"));
        System.out.println(s3);
    }
}
